const defaultVsSource = `
       attribute vec4 a_position;
          void main() {
              gl_Position = a_position;
              gl_PointSize = 10.0;
            }
      `
const defaultFsSource = `
    precision mediump float;
      void main() {
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
      }
      `
function loadShader(gl, type, source) {
  const shader = gl.createShader(type)

  // Send the source to the shader object

  gl.shaderSource(shader, source)

  // Compile the shader program

  gl.compileShader(shader)

  // See if it compiled successfully

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error(
      `An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`
    )
    gl.deleteShader(shader)
    return null
  }

  return shader
}
function initShaderProgram(gl, vsSource, fsSource) {
  const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource)
  const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource)

  // 建立 shader 程式
  const shaderProgram = gl.createProgram()
  gl.attachShader(shaderProgram, vertexShader)
  gl.attachShader(shaderProgram, fragmentShader)
  gl.linkProgram(shaderProgram)

  // 錯誤處理
  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    console.error(
      `Unable to initialize the shader program: ${gl.getProgramInfoLog(
        shaderProgram
      )}`
    )
    return null
  }

  return shaderProgram
}
const generateProgramInfo = (
  gl,
  vsSource = defaultVsSource,
  fsSource = defaultFsSource
) => {
  const shaderProgram = initShaderProgram(gl, vsSource, fsSource)
  const programInfo = {
    program: shaderProgram,
    attribLocations: {
      vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),
    },
    uniformLocations: {
      projectionMatrix: gl.getUniformLocation(
        shaderProgram,
        "uProjectionMatrix"
      ),
      modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),
      isInverting: gl.getUniformLocation(shaderProgram, "isInverting"),
      showTraversal: gl.getUniformLocation(shaderProgram, "showTraversal"),
      showRemaining: gl.getUniformLocation(shaderProgram, "showRemaining"),
    },
  }
  return programInfo
}

function dist(x1, y1, x2, y2) {
  return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
}

function initBuffers(gl, width, height) {
  // 建立一個 buffer 來儲存正方形的座標

  const positionBuffer = gl.createBuffer()

  // Select the positionBuffer as the one to apply buffer
  // operations to from here out.

  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)

  // Now create an array of positions for the square.

  const positions = [0, 0, width, 0, 0, -height, width, -height]

  // Now pass the list of positions into WebGL to build the
  // shape. We do this by creating a Float32Array from the
  // JavaScript array, then use it to fill the current buffer.

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)

  return {
    position: positionBuffer,
  }
}

//============================================================//
const drawFlat = (canvas, gl) => {
  const programInfo = generateProgramInfo(gl)
  console.log(programInfo)
}
//------------------------------------------------------------
const draw = () => {
  gl.viewport(0, 0, canvas.width, canvas.height)
  gl.clearColor(0.94, 0.94, 0.94, 1)

  // eslint-disable-next-line no-bitwise
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
  gl.enable(gl.BLEND)

  drawFlat(canvasRef, gl)

  requestAnimationFrame(draw)
}
draw()

//------------------------------------------------------------
function useAttrs() {
  gl.drawArrays(gl.LINES, 0, 8)
  gl.vertexAttribPointer(0, 4, 5126, false, stride, offset + 4)
  gl.enableVertexAttribArray(0)
  gl.vertexAttribPointer(1, 1, 5126, false, stride, offset + 0)
  gl.enableVertexAttribArray(1)
  gl.vertexAttribPointer(2, 1, 5126, false, stride, offset + 20)
  gl.enableVertexAttribArray(2)
  gl.vertexAttribPointer(3, 1, 5126, false, stride, offset + 24)
  gl.enableVertexAttribArray(3)
  gl.vertexAttribPointer(4, 1, 5126, false, stride, offset + 28)
  gl.enableVertexAttribArray(4)
  next()
  gl.disableVertexAttribArray(0)
  gl.disableVertexAttribArray(1)
  gl.disableVertexAttribArray(2)
  gl.disableVertexAttribArray(3)
  gl.disableVertexAttribArray(4)
}
//------------------------------------------------------------
function useUniforms() {
  let { perspective, view, scale, translate, color } = props
  let gl = drawCommands.gl
  if (perspective !== this.perspective) {
    gl.uniformMatrix4fv(this.perspective_location, false, perspective)
    this.perspective = perspective
  }
  if (view !== this.view) {
    gl.uniformMatrix4fv(this.view_location, false, view)
    this.view = view
  }
  if (scale !== this.scale) {
    gl.uniform3fv(this.scale_location, scale)
    this.scale = scale
  }
  if (translate !== this.translate) {
    gl.uniform3fv(this.translate_location, translate)
    this.translate = translate
  }
  if (color !== this.color) {
    gl.uniform4fv(this.color_location, color)
    this.color = color
  }
  next()
}

const programIn = {
  program: {},
  uniforms: [
    {
      name: "perspective",
      size: 1,
      type: 35676,
      location: {},
    },
    {
      name: "view",
      size: 1,
      type: 35676,
      location: {},
    },
    {
      name: "scale",
      size: 1,
      type: 35665,
      location: {},
    },
    {
      name: "translate",
      size: 1,
      type: 35665,
      location: {},
    },
    {
      name: "color",
      size: 1,
      type: 35666,
      location: {},
    },
  ],
  attrs: [
    {
      offset: 0,
      name: "position",
      size: 3,
      type: 5126,
    },
  ],
  perspective_location: {},
  view_location: {},
  scale_location: {},
  translate_location: {},
  color_location: {},
}
